package com.example.framework.common.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.excel.EasyExcel;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ExcelUtils {

    public static <T> void export(String fileName, String sheetName, List<T> dataList, Class<T> clazz, HttpServletResponse response) {
        //调用方法进行写操作
        EasyExcel.write(handleResponse(response, fileName), clazz)
                .sheet(sheetName)
                .doWrite(dataList);
    }

    public static <T> void exportDetail(String fileName, LinkedHashMap<String, String> headerAliasMap, List<T> data, HttpServletResponse response) {
        ExcelWriter writer = ExcelUtil.getWriter(true);

        // 标题
        for (Map.Entry<String, String> entry : headerAliasMap.entrySet()) {
            writer.addHeaderAlias(entry.getKey(), entry.getValue());
        }

        // 只输入指定字段
        writer.setOnlyAlias(true);

        writer.write(data);

        ServletOutputStream servletOutputStream = handleResponse(response, fileName);

        writer.flush(servletOutputStream, true);
        writer.close();
        IoUtil.close(servletOutputStream);
    }

    @SneakyThrows
    private static ServletOutputStream handleResponse(HttpServletResponse response, String fileName) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        String fileNameUtf = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileNameUtf + ".xlsx");
        response.setHeader("fileName", fileNameUtf + ".xlsx");
        // 暴露fileName的请求头
        response.setHeader("Access-Control-Expose-Headers", "fileName");
        return response.getOutputStream();
    }

}
